package com.huike.pmps.controller;

import com.huike.pmps.model.entity.Member;
import com.huike.pmps.model.entity.SupplierAttachment;
import com.huike.pmps.model.vo.Result;
import com.huike.pmps.service.*;
import com.huike.pmps.utils.TokenUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
import java.util.regex.Pattern;

/**
 * 作者：谌贵斌(黑桃K)
 * 日期: 2888-08-08
 * 老师QQ: 272488352
 * 官方QQ交流群: 377748272
 * 刀客程序员官网：http://www.daoke360.com
 * 刀客程序员淘宝旗舰店：https://daoke360.taobao.com/
 */
@RestController
@RequestMapping("/api/file")
@Api(tags = "文件上传、下载、导入、导出")
@Slf4j
public class FileController {
    @Value("${spring.servlet.multipart.location}")
    private String uploadFilePath;

    @Autowired
    private ResourceLoader resourceLoader;
    @Autowired
    private POService poService;
    @Autowired
    private POCourseService poCourseService;
    @Autowired
    private POCourseSupplierDetailService poCourseSupplierDetailService;
    @Autowired
    private SupplierSettlementDetailService supplierSettlementDetailService;
    @Autowired
    private SupplierService supplierService;
    @Autowired
    private SupplierWarehouseReceiptService supplierWarehouseReceiptService;
    @Autowired
    private SupplierAttachmentService supplierAttachmentService;
    @Autowired
    private PersonnelCostService personnelCostService;
    @Autowired
    private BusinessOpportunityService businessOpportunityService;
    @Autowired
    private ExpensesService expensesService;
    @Autowired
    private NewSignService newSignService;
    @Autowired
    private PaymentCollectionService paymentCollectionService;

    @ApiOperation(value = "驾驶舱-基础数据-回款数据导入", httpMethod = "POST")
    @ApiImplicitParam(name = "file", value = "文件", paramType = "query", dataType = "MultipartFile")
    @PostMapping("/import_payment_collection")
    public Result insertByImportPaymentCollection(MultipartFile file) {
        return paymentCollectionService.insertByImportPaymentCollection(file);
    }

    @ApiOperation(value = "驾驶舱-基础数据-新签数据导入", httpMethod = "POST")
    @ApiImplicitParam(name = "file", value = "文件", paramType = "query", dataType = "MultipartFile")
    @PostMapping("/import_new_sign")
    public Result insertByImportNewSignService(MultipartFile file) {
        return newSignService.insertByImportNewSignService(file);
    }

    @ApiOperation(value = "驾驶舱-基础数据-支出数据导入", httpMethod = "POST")
    @ApiImplicitParam(name = "file", value = "文件", paramType = "query", dataType = "MultipartFile")
    @PostMapping("/import_expenses")
    public Result insertByImportExpenses(MultipartFile file) {
        return expensesService.insertByImportExpenses(file);
    }

    @ApiOperation(value = "驾驶舱-基础数据-商机数据导入", httpMethod = "POST")
    @ApiImplicitParam(name = "file", value = "文件", paramType = "query", dataType = "MultipartFile")
    @PostMapping("/import_business_opportunity")
    public Result insertByImportBusinessOpportunity(MultipartFile file) {
        return businessOpportunityService.insertByImportBusinessOpportunity(file);
    }

    @ApiOperation(value = "驾驶舱-基础数据-人员成本数据导入", httpMethod = "POST")
    @ApiImplicitParam(name = "file", value = "文件", paramType = "query", dataType = "MultipartFile")
    @PostMapping("/import_personnel_cost")
    public Result insertByImportPersonnelCost(@RequestParam("file") MultipartFile file) {
        return personnelCostService.insertByImportPersonnelCost(file);
    }


    @ApiOperation(value = "新合同导入", httpMethod = "POST")
    @ApiImplicitParam(name = "file", value = "文件", paramType = "query", dataType = "MultipartFile")
    @PostMapping("/import_new_contract")
    public Result insertByImportNewContract(@RequestParam("file") MultipartFile file) {
        return poService.insertByImportNewContract(file);
    }

    @ApiOperation(value = "PO数据导入", httpMethod = "POST")
    @ApiImplicitParam(name = "file", value = "文件", paramType = "query", dataType = "MultipartFile")
    @PostMapping("/import_po")
    public Result insertByImportOldPo(@RequestParam("file") MultipartFile file) {
        return poService.insertByImportOldPo(file);
    }

    @ApiOperation(value = "PO数据导出", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "po", value = "po单号", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "customerName", value = "客户名称", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "contractNo", value = "合同编号", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "regionName", value = "战区名称", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "provinceName", value = "省份名称", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "poState", value = "po状态(1未启动、2进行中、3已交付、4已验收、5已完结、6已终止、7已过期)", paramType = "query", dataType = "int")
    })
    @GetMapping("/export_po")
    public void exportPO(HttpServletRequest request, HttpServletResponse response, String po, String customerName, String contractNo, String regionName, String provinceName,String teamName, Integer poState) {
        //从请求头中获取token
        Member member = (Member) request.getSession().getAttribute(TokenUtil.getToken(request));
        poService.exportPO(response, po, customerName, contractNo, regionName, provinceName,teamName, poState, member);
    }


    @ApiOperation(value = "PO课程导入", httpMethod = "POST")
    @ApiImplicitParam(name = "file", value = "文件", paramType = "query", dataType = "MultipartFile")
    @PostMapping("/import_po_course")
    public Result insertByImportPoCourse(@RequestParam("file") MultipartFile file) {
        return poCourseService.insertByImportPoCourse(file);
    }


    @ApiOperation(value = "课程进度列表导出", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "po", value = "po单号", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "customerName", value = "客户名称", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "regionName", value = "战区", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "provinceName", value = "省份名称", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "courseName", value = "课程名称", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "courseChargeName", value = "课程编导", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "courseState", value = "课程状态", paramType = "query", dataType = "String"),
    })
    @GetMapping("/export_po_course")
    public void exportPOCourse(HttpServletRequest request, HttpServletResponse response, String po, String customerName, String regionName, String provinceName,String teamName, String courseName, String courseChargeName, String courseState) {
        //从请求头中获取token
        Member member = (Member) request.getSession().getAttribute(TokenUtil.getToken(request));
        poCourseService.exportPOCourse(response,member,po,customerName,regionName,provinceName,teamName,courseName,courseChargeName,courseState);
    }

    @ApiOperation(value = "供应商分配导入", httpMethod = "POST")
    @ApiImplicitParam(name = "file", value = "文件", paramType = "query", dataType = "MultipartFile")
    @PostMapping("/import_course_supplier")
    public Result insertByImportPOCourseSupplierDetail(MultipartFile file) {
        return poCourseSupplierDetailService.insertByImportPOCourseSupplierDetail(file);
    }

    @ApiOperation(value = "供应商分配总表导出", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "po", value = "po单号", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "customerName", value = "客户名称", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "regionName", value = "战区", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "provinceName", value = "省份名称", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "courseName", value = "课程名称", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "courseChargeName", value = "课程编导", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "supplierName", value = "供应商名称", paramType = "query", dataType = "String"),
    })
    @GetMapping("/export_course_supplier")
    public void exportCourseSupplier(HttpServletRequest request, HttpServletResponse response, String po, String customerName, String regionName, String provinceName, String courseName, String courseChargeName, String supplierName) {
        //从请求头中获取token
        Member member = (Member) request.getSession().getAttribute(TokenUtil.getToken(request));
        poCourseSupplierDetailService.exportCourseSupplier(response, po, customerName, regionName, provinceName, courseName, courseChargeName, supplierName, member);
    }

    @ApiOperation(value = "供应商结算总表导入", httpMethod = "POST")
    @ApiImplicitParam(name = "file", value = "文件", paramType = "query", dataType = "MultipartFile")
    @PostMapping("/import_settlement_list")
    public Result importImportSupplierSettlementDetail(MultipartFile file) {
        return supplierSettlementDetailService.insertByImportSupplierSettlementDetail(file);
    }

    @ApiOperation(value = "供应商结算总表导出", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "po", value = "po单号", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "customerName", value = "客户名称", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "regionName", value = "战区", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "provinceName", value = "省份名称", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "courseName", value = "课程名称", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "courseChargeName", value = "课程编导", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "supplierName", value = "供应商名称", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "paymentStateName", value = "支付状态", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "taxPoint", value = "税点", paramType = "query", dataType = "String")

    })
    @GetMapping("/export_settlement_list")
    public void exportSettlementList(HttpServletRequest request, HttpServletResponse response, String po, String customerName, String regionName, String provinceName, String courseName, String courseChargeName, String supplierName, String paymentStateName, String taxPoint) {
        //从请求头中获取token
        Member member = (Member) request.getSession().getAttribute(TokenUtil.getToken(request));
        supplierSettlementDetailService.exportSupplierSettlement(response, po, customerName, regionName, provinceName, courseName, courseChargeName, supplierName, member, paymentStateName, taxPoint);
    }


    @ApiOperation(value = "入库课程总览导出", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "customerName", value = "客户名称", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "supplierName", value = "供应商名称", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "courseChargeName", value = "课程编导", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "courseName", value = "课程名称", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "courseQualityEvaluation", value = "课程质量评价", paramType = "query", dataType = "int")
    })
    @GetMapping("/export_warehouse_receipt")
    public void exportSupplier(HttpServletRequest request, HttpServletResponse response, String customerName, String supplierName, String courseChargeName, String courseName, Integer courseQualityEvaluation) {
        //从请求头中获取token
        Member member = (Member) request.getSession().getAttribute(TokenUtil.getToken(request));
        supplierWarehouseReceiptService.exportWarehouseReceipt(response, customerName, supplierName, courseChargeName, member, courseName, courseQualityEvaluation);
    }


    @ApiOperation(value = "供应商基本信息导入", httpMethod = "POST")
    @ApiImplicitParam(name = "file", value = "文件", paramType = "query", dataType = "MultipartFile")
    @PostMapping("/import_supplier")
    public Result importSupplier(@RequestParam("file") MultipartFile file) {
        return supplierService.insertImportSupplier(file);
    }

    @ApiOperation(value = "供应商导出", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "supplierName", value = "供应商名称", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "supplierTypeId", value = "供应商类型ID", paramType = "query", dataType = "int"),
            @ApiImplicitParam(name = "provinceName", value = "所属区域", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "serviceTypeName", value = "服务范围", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "contractState", value = "合同状态", paramType = "query", dataType = "String")
    })
    @GetMapping("/export_supplier")
    public void exportSupplier(HttpServletResponse response, String supplierName, Integer supplierTypeId, String provinceName, String serviceTypeName, String contractState) {
        supplierService.exportSupplier(response, supplierName, supplierTypeId, provinceName, serviceTypeName, contractState);
    }


    @ApiOperation(value = "供应商附件上传", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "supplierId", value = "po详情课程id", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "type", value = "附件类型(1视频样片、2音频文件、3效果图、4相关文档)", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "file", value = "文件", paramType = "query", dataType = "MultipartFile")
    })
    @PostMapping("/supplier_attachments/upload")
    public Result uploadSupplierAttachments(String supplierId, String type, @RequestParam("file") MultipartFile multipartFile) {
        String childPath = "/supplier/" + supplierId;
        String filePath = uploadFile(childPath, multipartFile);
        SupplierAttachment supplierAttachment = SupplierAttachment.builder().supplierId(supplierId).type(type).createTime(new Date()).fileName(multipartFile.getOriginalFilename()).filePath(filePath).build();
        return supplierAttachmentService.insertOne(supplierAttachment);
    }


    @ApiOperation(value = "PO课程验收单上传", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "记录ID", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "receptTimeLength", value = "验收时长", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "file", value = "文件", paramType = "query", dataType = "MultipartFile")
    })
    @PostMapping("/course_acceptance_report/upload")
    public Result uploadAcceptanceReport(Integer id,String receptTimeLength, @RequestParam("file") MultipartFile multipartFile) {
        //判断验收时长不能为空
        if(StringUtils.isBlank(receptTimeLength) || StringUtils.isEmpty(receptTimeLength)){
            return Result.failure("验收时长不能为空");
        }
        //判断验收时长是否符合格式要求 12:12:12
        String pattern = "^[0-9]*:[0-5]\\d:[0-5]\\d$";
        boolean isMatch = Pattern.matches(pattern, receptTimeLength);
        if(!isMatch){
            return Result.failure("验收时长格式不正确");
        }
        String childPath = "/po_course/" + id;
        String filePath = uploadFile(childPath, multipartFile);
        return poCourseService.updateAcceptanceReport(id, receptTimeLength,multipartFile.getOriginalFilename(), filePath, new Date());
    }

    @ApiOperation(value = "文件下载", httpMethod = "GET")
    @GetMapping("/download/**/{fileName:.+}")
    public ResponseEntity<Resource> download(HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        try {
            String filePath = "file:" + uploadFilePath + requestURI.split("download")[1];
            HttpHeaders headers = new HttpHeaders();
            headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
            // headers.add("Content-Disposition", "attachment; filename=" + file.getName());
            headers.add("Pragma", "no-cache");
            headers.add("Expires", "0");
            headers.add("Last-Modified", new Date().toString());
            headers.add("ETag", String.valueOf(System.currentTimeMillis()));

            return ResponseEntity.ok().headers(headers)
                    .contentType(MediaType.parseMediaType("application/octet-stream")).body(resourceLoader.getResource(filePath));

        } catch (Exception e) {
            return ResponseEntity.notFound().build();
        }
    }


   /* public ResponseEntity<FileSystemResource> export(File file) {
        if (file == null) {
            return null;
        }
        HttpHeaders headers = new HttpHeaders();
        headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
        headers.add("Content-Disposition", "attachment; filename=" + file.getName());
        headers.add("Pragma", "no-cache");
        headers.add("Expires", "0");
        headers.add("Last-Modified", new Date().toString());
        headers.add("ETag", String.valueOf(System.currentTimeMillis()));
        return ResponseEntity
                .ok()
                .headers(headers)
                .contentLength(file.length())
                .contentType(MediaType.parseMediaType("application/octet-stream"))
                .body(new FileSystemResource(file));
    }*/

    private String uploadFile(String childPath, MultipartFile multipartFile) {
        // 把文件的名称设置唯一值，uuid
        String uuid = UUID.randomUUID().toString().replace("-", "");
        //获取文件扩展名
        String suffix = multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().lastIndexOf(".") + 1).toLowerCase();
        //判断文档类型
        childPath = childPath + "/" + new SimpleDateFormat("yyyy_MM_dd").format(new Date());
        File file = new File(uploadFilePath + childPath);
        if (!file.exists()) {
            file.mkdirs();
        }
        String fileName = uuid + "." + suffix;
        //将收到的文件传输到目标文件中
        try {
            multipartFile.transferTo(new File(file, fileName));
        } catch (IOException e) {
            log.error(e.getMessage());
            e.printStackTrace();
        }
        return childPath + "/" + fileName;
    }


}
